#include "JeuCombat_private.h"

Jeu* newJeuCombat(Jeu* jeu){
	eassert(jeu != NULL);
	
	jeuSetMode(jeu,mjCombat);
	jeuCombatSetCombattants(jeu,newList());
	jeuCombatSetIt(jeu,newListIt(jeuCombatGetCombattants(jeu)));
	
	return jeu;
}

Jeu* deleteJeuCombat(Jeu* jeu){
	eassert(jeu != NULL);
	
	jeuSetMode(jeu,mjPlateau);
	deleteList(jeuCombatGetCombattants(jeu));
	deleteListIt(jeuCombatGetIt(jeu));
	
	jeuCombatSetCombattants(jeu,NULL);
	jeuCombatSetIt(jeu,NULL);
	
	return jeu;
}

int jeuCombatExecuter(Jeu* jeu){
	List* ennemis; /*< liste des ennemis d'un personnage au moment du combat */
	ListIterator* it; /*< Iterator utilisé pour itéré dans la liste des combattants */
	Pouvoir* pouvoir; /*< pouvoir du personnage en train de se battre */
	Personnage* perso, *ennemi; /*< personnages ennemis */
	Joueur* joueur; /* joueur du personnage se battant */
	
	
	eassert(jeuGetMode(jeu) == mjCombat);
	
	/* TODO : jeuCombatExecuter */
	it = jeuCombatGetIt(jeu);
	
	listItForEachInfinite(perso,it){
		/* Si le perso est mort (et oui... ça arrive :p), il ne peut pas jouer.. */
		if(persoIsMort(perso)) continue;
		
		/* Si il est bloqué.. ba pas mieu hein! :p */
		if(persoIsFreezed(perso)){
			persoUnFreeze(perso);
			continue;
		}
		
		/* Utilise un pouvoir spécial si possible */
		pouvoir = persoGetPouvoir(perso);
		joueur = persoGetJoueur(perso);
		if(pouvoirCanUseItNow(pouvoir,jeu)){
			if(joueurAskUsePouvoir(joueur,pouvoir))
				pouvoirAppliquer(pouvoir,jeu);
		}
		
		/* Attaque un ennemi */
		ennemis = newList();
		
		jeuCombatGetEnnemis(jeu,ennemis);
		ennemi = joueurAskChooseEnnemi(joueur,ennemis);
		persoAttaquer(perso,ennemi);
		
		deleteList(ennemis);
		
		/* Si l'ennemi a été tué et qu'il n'en reste pas d'autres on arrete le combat */
		if(persoIsMort(ennemi))
			if(!jeuCombatIsThereAnyoneAlive(ennemis)) break;
		
	}
	
	return 1;
}

List* jeuCombatGetCombattants(Jeu* jeu){
	eassert(jeu != NULL);
	
	return jeu->u.combat.combatants;
}

ListIterator* jeuCombatGetIt(Jeu* jeu){
	eassert(jeu != NULL);
	
	return jeu->u.combat.it;
}

Personnage* jeuCombatGetPerso(Jeu* jeu){
	eassert(jeuGetMode(jeu) == mjCombat);
	
	return (Personnage*)listItGetCurrent(jeuCombatGetIt(jeu));
}

int jeuCombatGetEnnemis(Jeu* jeu,List* ennemis){
	Joueur* currentPlayer;
	Personnage* nPerso;
	List* combatants;
	
	assert(jeuGetMode(jeu) == mjCombat);
	
	combatants = jeuCombatGetCombattants(jeu);

	currentPlayer = persoGetJoueur(jeuCombatGetPerso(jeu));
	listForEach(nPerso,combatants){
		if(persoGetJoueur(nPerso) != currentPlayer)
			listInsertLast(ennemis,nPerso);
	}
	
	return listGetSize(ennemis);
}

void jeuCombatSetCombattants(Jeu* jeu,List* combattants){
	eassert(jeu != NULL);
	
	jeu->u.combat.combatants = combattants;
}

void jeuCombatSetIt(Jeu* jeu,ListIterator* it){
	eassert(jeu != NULL);
	
	jeu->u.combat.it = it;
}

int jeuCombatAddCombattant(Jeu* jeu,Personnage* perso){
	eassert(jeu != NULL);
	eassert(perso != NULL);
	
	if(listPosOf(jeuCombatGetCombattants(jeu),perso) != LIST_INVALIDPOS) return 0;
	
	listInsertLast(jeuCombatGetCombattants(jeu),perso);
	
	return 1;
}

/* Static Functions */
int jeuCombatIsThereAnyoneAlive(List* listPerso){
	Personnage* perso;
	
	listForEach(perso,listPerso)
		if(!persoIsMort(perso)) return 1;
	return 0;
}
